package cn.rengy.tool.crypto;

import cn.rengy.util.ExceptionPrintUtils;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.binary.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
 * 
 * @author rengy
 *
 */
public class AES {
	private static Logger logger = LoggerFactory.getLogger(AES.class);
	private static int 密钥长度 = 128;
	private static String 算法名称 = "AES";
	private static String 转换模式 = "AES";// 默认 AES/CBC/PKCS5Padding
	/**
	 * 加密
	 * @param plaintext 明文
	 * @param secretKey 密钥
	 * @return 密文的HexString形式
	 */
	public static String encryptHex(String plaintext, String secretKey){
		Cipher cipher=null;
		try {
			cipher = Cipher.getInstance(转换模式);// 格式“算法/模式/填充”或 “算法”
			cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(secretKey));
		} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
			logger.error("错误的算法名称：{}",转换模式);
			throw new RuntimeException(e);
		} catch (InvalidKeyException e) {
			logger.error("无效的key(无效编码、错误长度、未初始化等)");
			throw new RuntimeException(e);
		}
		String result=null;
		try {
			result = Hex.encodeHexString(cipher.doFinal(StringUtils.getBytesUtf8(plaintext)));
		} catch (IllegalBlockSizeException | BadPaddingException e) {
			logger.error(ExceptionPrintUtils.getTrace(e));
		}
		return result;

	}
	/**
	 * 解密
	 * @param hexCipherText HexString形式密文
	 * @param secretKey 密钥
	 * @return 明文
	 */
	public static String decryptHex(String hexCipherText, String secretKey) {
		Cipher cipher=null;
		try {
			cipher = Cipher.getInstance(转换模式);
			cipher.init(Cipher.DECRYPT_MODE, getSecretKey(secretKey));
		} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
			logger.error("错误的算法名称：{}",转换模式);
			return null;
		}catch (InvalidKeyException e) {
			logger.error("无效的key(无效编码、错误长度、未初始化等)");
			return null;
		}// 解密模式 
		String result=null;
		try {
			result = StringUtils.newStringUtf8(cipher.doFinal(Hex.decodeHex(hexCipherText.toCharArray())));
		} catch (IllegalBlockSizeException | BadPaddingException | DecoderException e) {
			logger.error(ExceptionPrintUtils.getTrace(e));
		}
		return result;
	}

	public static String decrypt(byte[] cipherText, String secretKey) {
		Cipher cipher=null;
		try {
			cipher = Cipher.getInstance(转换模式);
			cipher.init(Cipher.DECRYPT_MODE, getSecretKey(secretKey));
		} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
			logger.error("错误的算法名称：{}",转换模式);
			return null;
		}catch (InvalidKeyException e) {
			logger.error("无效的key(无效编码、错误长度、未初始化等)");
			return null;
		}// 解密模式
		String result=null;
		try {
			result = StringUtils.newStringUtf8(cipher.doFinal(cipherText));
		} catch (IllegalBlockSizeException | BadPaddingException e) {
			logger.error(ExceptionPrintUtils.getTrace(e));
		}
		return result;
	}

	private static Key getSecretKey(final String secretKey) throws NoSuchAlgorithmException {

		KeyGenerator kgen = KeyGenerator.getInstance(算法名称);
		SecureRandom secureRandom=SecureRandom.getInstance("SHA1PRNG");
		secureRandom.setSeed(StringUtils.getBytesUtf8(secretKey));
		kgen.init(密钥长度, secureRandom);// SecureRandom是生成安全随机数序列， 只要种子相同，序列就一样
		//有什么区别？
		return new SecretKeySpec(kgen.generateKey().getEncoded(), 算法名称);
		//return kgen.generateKey();
	}
	

}
